/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.rafkind.crawl.data.team;

import com.rafkind.crawl.battle.Battle;
import com.rafkind.crawl.battle.BattleCommand;
import com.rafkind.crawl.battle.BattleListener;
import com.rafkind.crawl.battle.command.AttackCommand;
import com.rafkind.crawl.battle.command.DefendCommand;
import com.rafkind.crawl.data.Creature;
import com.rafkind.crawl.data.Effect;
import com.rafkind.crawl.data.Team;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 *
 * @author drafkind
 */
public class PlayerTeam extends Team implements BattleListener {

  private Map<Creature, Request> nextRoundsCommands;

  public PlayerTeam() {
    this.nextRoundsCommands = new HashMap<Creature, Request>();
  }
  
  
  @Override
  public BattleCommand getBattleCommandFor(Creature creature) {
    Request r = nextRoundsCommands.get(creature);
    
    if (r != null) {
      switch (r.getAction()) {      
	case ATTACK: 
	  return new AttackCommand(new Random(), creature, r.getTargets());	
      }
    }
    
    return new DefendCommand(creature);
  }

  public void afterActorAction(Battle battle, Creature creature) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  public void afterActorDecision(Battle battle, Creature creature) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  public void attackDamage(Creature source, Effect effect, Creature target, int damage) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  public void attackHit(Creature source, Effect effect, Creature target) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  public void attackMiss(Creature source, Effect effect, Creature target) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  public void battleStart(Battle battle) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  public void beforeActorAction(Battle battle, Creature creature) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  public void beforeActorDecision(Battle battle, Creature creature) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  public void roundStart(Battle battle) {
    List<Creature> whosLeft = new ArrayList<Creature>();
    for (Creature c : getMembers()) {
      if (c.isActiveInBattle())
	whosLeft.add(c);
    }
    
    nextRoundsCommands.clear();
    
    List<Action> actions = new ArrayList<Action>();
    for (Action a : Action.values())
      actions.add(a);
    
    List<Creature> targets = new ArrayList<Creature>();
    for (Creature c : opposingTeam.getMembers()) {
      if (c.isActiveInBattle())
	targets.add(c);
    }
    
    int index = 0;
    while (index < whosLeft.size()) {
      Creature source = whosLeft.get(index);
      Action action = new TextMenu<Action>(source.getName() + ": what do you do? ",
	  actions, (index > 0)).get();
      
      if (action == null) {
	index--;
      } else {
	if (action == Action.ATTACK || action == Action.CAST_SPELL || action == Action.USE_ITEM) {
	  Creature target = new TextMenu<Creature>(source.getName() + ": who do you do it to? ",
	      targets, true).get();

	  if (target != null) {
	    List<Creature> t = new ArrayList<Creature>();
	    t.add(target);
	    nextRoundsCommands.put(source, new Request(action, t));
	  }
	} else {
	  nextRoundsCommands.put(source, new Request(action));
	}
	index++;
      }      
    }
  }

  public static enum Action {
    ATTACK("Attack"),    
    CAST_SPELL("Cast a spell"),
    USE_ITEM("Use an item"),
    DEFEND("Defend"),
    RUN("Run");
    
    private String name;
    
    Action(String n) {
      name = n;
    }

    @Override
    public String toString() {
      return name;
    }    
  }
  
  public static class Request {
    private Action action;
    private List<Creature> targets;

    public Request(Action action, List<Creature> targets) {
      this.action = action;
      this.targets = targets;
    }
    
    public Request(Action action) {
      this.action = action;
      this.targets = new ArrayList<Creature>();
    }

    public Action getAction() {
      return action;
    }

    public List getTargets() {
      return targets;
    }   
  }
}